import numpy as np
import pandas as pd
pd.options.display.max_colwidth = 300
import datetime
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import joypy
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn import metrics
import re
RANDOM_SEED = 42
!pip freeze > requirements.txt
# Функция для анализа содержимого датафрейма
def df_types(df_input):
columns_exch = {"<class 'str'>": 'str', "<class 'float'>": 'float', "<class 'int'>": 'int'}
df_output = pd.DataFrame(
df_input[df_input[c].notna()][c].apply(type).value_counts() for c in df_input.columns
).fillna(0).astype(int)
if df_input.isna().any().any():
df_output['NaN'] = df_input.isna().sum()
df_output['sum'] = df_output.sum(axis=1)
df_output.columns = [columns_exch[str(x)] if str(x) in columns_exch else x for x in df_output.columns]
display(df_output.head(60))
df_input = pd.read_excel('yandex_hack.xlsx', 'result 1')
df_types(df_input) # запуск функции для анализа данных
df_input.columns
| str | float | int | NaN | sum | |
|---|---|---|---|---|---|
| order_created_datetime | 66464 | 0 | 0 | 0 | 66464 |
| brand_name | 66464 | 0 | 0 | 0 | 66464 |
| rest_id | 66464 | 0 | 0 | 0 | 66464 |
| batched_with_order_id | 442 | 0 | 0 | 66022 | 66464 |
| order_id | 66464 | 0 | 0 | 0 | 66464 |
| first_in_multiorder_flg | 0 | 442 | 0 | 66022 | 66464 |
| courier_id | 66202 | 0 | 0 | 262 | 66464 |
| order_items_cnt | 0 | 0 | 66464 | 0 | 66464 |
| city | 66464 | 0 | 0 | 0 | 66464 |
Index(['order_created_datetime', 'brand_name', 'rest_id',
'batched_with_order_id', 'order_id', 'first_in_multiorder_flg',
'courier_id', 'order_items_cnt', 'city'],
dtype='object')
df = df_input.copy() # работаем с копией загруженного датасета, чтобы не повторять загрузку
df.describe(include = 'all') # изучаем структуру данных
| order_created_datetime | brand_name | rest_id | batched_with_order_id | order_id | first_in_multiorder_flg | courier_id | order_items_cnt | city | |
|---|---|---|---|---|---|---|---|---|---|
| count | 66464 | 66464 | 66464 | 442 | 66464 | 442.000000 | 66202 | 66464.000000 | 66464 |
| unique | 55076 | 2 | 1098 | 442 | 66464 | NaN | 9053 | NaN | 32 |
| top | 2015-09-15 10:24:05.000000 | B | 7cc98331ddb8ccffe464455f3df763d9 | cd51180695ac23bead7ff649d9cba8ab | 8daeb2e565d74f9ae58ddbd3fe3bfa1b | NaN | 5b17547f825d9cf35c7853621dd842f8 | NaN | e6705560085199e9674cd721ee844d0d |
| freq | 6 | 56835 | 606 | 1 | 1 | NaN | 643 | NaN | 40700 |
| mean | NaN | NaN | NaN | NaN | NaN | 0.500000 | NaN | 4.658778 | NaN |
| std | NaN | NaN | NaN | NaN | NaN | 0.500567 | NaN | 3.200722 | NaN |
| min | NaN | NaN | NaN | NaN | NaN | 0.000000 | NaN | 1.000000 | NaN |
| 25% | NaN | NaN | NaN | NaN | NaN | 0.000000 | NaN | 3.000000 | NaN |
| 50% | NaN | NaN | NaN | NaN | NaN | 0.500000 | NaN | 4.000000 | NaN |
| 75% | NaN | NaN | NaN | NaN | NaN | 1.000000 | NaN | 6.000000 | NaN |
| max | NaN | NaN | NaN | NaN | NaN | 1.000000 | NaN | 108.000000 | NaN |
print('Количество заказов с брендом A:', 66464 - 56835) # подсчитаем заказы с брендом A
print('Количество заказов с брендом B:', 56835) # подсчитаем заказы с брендом B
Количество заказов с брендом A: 9629 Количество заказов с брендом B: 56835
print('Бизнес-метрика (доля мультизаказов) для бренда A:', 442 / 9629) # подсчитаем долю мультизаказов
Бизнес-метрика (доля мультизаказов) для бренда A: 0.04590300135008828
df.sample(3) # посмотрим на случайную выборку записей
| order_created_datetime | brand_name | rest_id | batched_with_order_id | order_id | first_in_multiorder_flg | courier_id | order_items_cnt | city | |
|---|---|---|---|---|---|---|---|---|---|
| 42014 | 2015-09-14 08:34:58.000000 | B | 85ed24e7cf8f7dc7bd2cb44c5b92011e | NaN | e40cbbb4754b13f76d04f55711171ac3 | NaN | e053f6eefd618ac0d7b9177e8ab099c0 | 3 | e6705560085199e9674cd721ee844d0d |
| 41233 | 2015-09-13 17:11:13.000000 | B | 6e34525dd103876184f9ffdf41321489 | NaN | 36ddc15ba974eedcb959d0c02addd468 | NaN | cc8909cf90b24cf93d74b4f4b630ff93 | 4 | e6705560085199e9674cd721ee844d0d |
| 58608 | 2015-09-16 06:18:11.000000 | B | 6395b78230c6912c237a8ccae6902f40 | NaN | 4229440157f5abe6205cae2980d00f28 | NaN | 2846e12ce9a178cc783bdf9f2c1f5f84 | 4 | e6705560085199e9674cd721ee844d0d |
df.nunique(dropna=False) # еще раз посмотрим, сколько уникальных значений в каждом поле
order_created_datetime 55076 brand_name 2 rest_id 1098 batched_with_order_id 443 order_id 66464 first_in_multiorder_flg 3 courier_id 9054 order_items_cnt 54 city 32 dtype: int64
df.groupby('rest_id').city.nunique().max() # проверим, может ли один ресторан быть в нескольких городах
1
Так как количество городов для каждого ресторана не превышает одного, то каждый ресторан находится только в одном городе
# Проверим, не повторяются ли номера заказов
df.order_id.nunique() == len(df)
True
Номера заказов не повторяются
df.groupby('brand_name').nunique()
| order_created_datetime | rest_id | batched_with_order_id | order_id | first_in_multiorder_flg | courier_id | order_items_cnt | city | |
|---|---|---|---|---|---|---|---|---|
| brand_name | ||||||||
| A | 9374 | 518 | 442 | 9629 | 2 | 4034 | 30 | 30 |
| B | 48412 | 580 | 0 | 56835 | 0 | 8638 | 54 | 31 |
df[df.batched_with_order_id.notna()].nunique()
order_created_datetime 442 brand_name 1 rest_id 99 batched_with_order_id 442 order_id 442 first_in_multiorder_flg 2 courier_id 209 order_items_cnt 17 city 1 dtype: int64
В эксперименте по доставке мультизаказов участвовало только 99 ресторанов в одном городе, задействовано 209 курьеров
#Преобразуем время
df.order_created_datetime = pd.to_datetime(df.order_created_datetime)
# Отделяем первые и вторые заказы для анализа для последующего вычисления временной разницы между заказами
df_frst = df[df['first_in_multiorder_flg']==1]
df_scnd = df[df['first_in_multiorder_flg']==0]
# Добавляем номер к колонкам для разделения
df_frst.columns = [str(col) + '_first' for col in df.columns]
df_scnd.columns = [str(col) + '_second' for col in df.columns]
# Cоединяем датасеты для вычисления временной разницы между заказами
df_model = df_frst.merge(df_scnd, left_on = 'batched_with_order_id_first', right_on = 'order_id_second')
# Добавляем колонку с вычисленной разницей во времени для определения критериев объединения заказов в мультизаказ
df_model['order_created_datetime_diff'] = abs(df_model['order_created_datetime_first'] -
df_model['order_created_datetime_second'])
# Создаем датасет для записи результатов анализа
df_analyse = pd.DataFrame()
# Проверяем соответствие между показателями для первого и второго заказов
for col in df.columns:
df_analyse[col] = (df_model[col + '_first'] == df_model[col + '_second'])
#Выводим список колонок с совпадающими значениями — это критерии к объединению заказов в мультизаказ
df_analyse.all(axis=0)
order_created_datetime False brand_name True rest_id True batched_with_order_id False order_id False first_in_multiorder_flg False courier_id True order_items_cnt False city True dtype: bool
# Для дат выводим разницу во времени в секундах
df_analyse['order_created_datetime'] = abs(df_model['order_created_datetime_first'] -
df_model['order_created_datetime_second']).dt.total_seconds()
# Посмотрим значения по разбросу дат заказа в секундах для визуального отображения на графике, убрав выброс в 8 часов
# обычная разница между временем заказа в районе получаса
fig = px.violin(df_analyse[df_analyse['order_created_datetime']<1500],
x = 'order_created_datetime', #y = 'city',
labels={'order_created_datetime': 'Время между заказами, сек'},
box=True,
points = 'all', # can be 'all', 'outliers', or False
orientation = 'h',
title = 'Распределение количества мультизаказов по времени между заказами'
)
fig.show()
# Разобьем по времени
conditions = [
(df_model['order_created_datetime_diff'] <= datetime.timedelta(minutes=5)),
(df_model['order_created_datetime_diff'] > datetime.timedelta(minutes=5)) & (df_model['order_created_datetime_diff'] <= datetime.timedelta(minutes=10)),
(df_model['order_created_datetime_diff'] > datetime.timedelta(minutes=10)) & (df_model['order_created_datetime_diff'] <= datetime.timedelta(minutes=15)),
(df_model['order_created_datetime_diff'] > datetime.timedelta(minutes=15)) & (df_model['order_created_datetime_diff'] <= datetime.timedelta(minutes=30)),
(df_model['order_created_datetime_diff'] > datetime.timedelta(minutes=30))
]
# группы
values = ['<5', '5-10', '10-15', '15-30', '>30']
# добавляем колонку по группам
df_model['time_group'] = np.select(conditions, values)
# Количество заказов по группам
df_model.groupby('time_group')['order_id_first'].nunique()
time_group 10-15 36 15-30 14 5-10 75 <5 94 >30 2 Name: order_id_first, dtype: int64
# Количество заказов по группам (в процентах)
df_model.groupby('time_group')['order_id_first'].nunique()/221*100
time_group 10-15 16.289593 15-30 6.334842 5-10 33.936652 <5 42.533937 >30 0.904977 Name: order_id_first, dtype: float64
df = df_input.copy() # работаем с копией загруженного датасета, чтобы не повторять загрузку
# Проверим сначала, что код '007' не используется в датасете
print('Количество записей с кодом «007» (должен быть 0):', sum(df.courier_id=='007'))
Количество записей с кодом «007» (должен быть 0): 0
df.courier_id.fillna('007', inplace=True)
print('Количество записей с кодом «007» (самовывоз):', sum(df.courier_id=='007'))
Количество записей с кодом «007» (самовывоз): 262
df.order_created_datetime = pd.to_datetime(df.order_created_datetime)
бренды, рестораны, курьеры, города в числовой формат для последующего анализа¶# Перекодируем бренды из {'A': 1, 'B': 0}
df.brand_name = df.brand_name.apply(lambda x: 1 if x=='A' else 0)
# Тестируем перекодировку ресторанов по рангу от количества заказов (для удобства)
df.groupby('rest_id').order_id.count().rank(method='first').nunique(),\
df.rest_id.nunique(dropna=False)
(1098, 1098)
Количество ресторанов c учетом самовывоза - 1098, без учета 1085
# Тестируем перекодировку курьеров по рангу от количества заказов (для удобства)
df.groupby('courier_id').order_id.count().rank(method='first').nunique(),\
df.courier_id.nunique(dropna=False)
(9054, 9054)
Количество курьеров - 9053, добавлен виртуальный курьер для заказов без указания курьера
# Тестируем перекодировку городов по рангу от количества заказов (для удобства)
df.groupby('city').order_id.count().rank(method='first').nunique(),\
df.city.nunique(dropna=False)
(32, 32)
Количество городов - 32
# Производим перекодировку ресторанов, курьеров, городов
df.rest_id = df.rest_id.map(
dict(df.groupby('rest_id').order_id.count().rank(ascending = False, method='first'))).astype(int)
df.courier_id = df.courier_id.map(
dict(df.groupby('courier_id').order_id.count().rank(ascending = False, method='first'))).astype(int)
df.city = df.city.map(
dict(df.groupby('city').order_id.count().rank(ascending = False, method='first'))).astype(int)
заказы по времени создания¶# Отсортируем датасет по ресторанам и времени создания заказов. Номер заказа — в index
df = df.sort_values(['brand_name', 'rest_id', 'order_created_datetime']).reset_index(drop=True)
# Добавим новые поля - order_count (флаг/количество заказов) и multiorder_count (флаг/количество мультизаказов)
df['order_count'] = 1 # каждая запись в датасете является одним заказом
df['multiorder_count'] = df.batched_with_order_id.notna().astype(int) # для мультизаказов всегда указан второй заказ
# Добавим новое поле - час, когда произведен заказ
df['order_hour'] = df.order_created_datetime.dt.hour
# Добавим новое поле - delta_time - время в минутах между заказами в одном магазине
df_prev = df.shift()
df['delta_time'] = (df.order_created_datetime - df_prev.order_created_datetime).dt.total_seconds()/60
# Добавим новое поле - co_order - соседний заказ
df['co_order'] = -1
df['pair_id'] = 0
df['co_first'] = -1
# Установим `бесконечное` время для интервалов между заказами в разных магазинах или брендах
df_filter = ((df_prev.brand_name==df.brand_name)&(df_prev.rest_id==df.rest_id))
df.delta_time.where(df_filter, np.inf, inplace = True)
pair_id=0
df_flag = dict(zip(df.index,[True]*len(df.index)))
for i in df[df_filter].sort_values('delta_time').index:
if df_flag[i] and df_flag[i-1]:
df_flag[i] = False
df_flag[i-1] = False
pair_id += 1
df.loc[i, 'pair_id'] = pair_id
df.loc[i, 'co_order'] = i-1
df.loc[i, 'co_first'] = 0
df.loc[i-1, 'pair_id'] = pair_id
df.loc[i-1, 'co_order'] = i
df.loc[i-1, 'co_first'] = 1
df.loc[i-1, 'delta_time'] = df.loc[i, 'delta_time']
# Удалим поля, из которых извлекли всю полезную информацию: order_id, batched_with_order_id, first_in_multiorder_flg
df.drop(['order_id', 'batched_with_order_id', 'first_in_multiorder_flg'], axis=1, inplace=True)
df.sample(5)
| order_created_datetime | brand_name | rest_id | courier_id | order_items_cnt | city | order_count | multiorder_count | order_hour | delta_time | co_order | pair_id | co_first | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 51118 | 2015-09-15 11:37:13 | 0 | 382 | 16 | 2 | 6 | 1 | 0 | 11 | 127.500000 | -1 | 0 | -1 |
| 38126 | 2015-09-15 18:31:04 | 0 | 190 | 6875 | 2 | 5 | 1 | 0 | 18 | 30.683333 | 38125 | 23490 | 0 |
| 24516 | 2015-09-13 21:50:31 | 0 | 92 | 6141 | 3 | 1 | 1 | 0 | 21 | 5.683333 | 24515 | 12928 | 0 |
| 41594 | 2015-09-13 12:27:37 | 0 | 226 | 7853 | 2 | 2 | 1 | 0 | 12 | 0.483333 | 41595 | 1898 | 1 |
| 19291 | 2015-09-14 17:57:12 | 0 | 65 | 3298 | 6 | 1 | 1 | 0 | 17 | 2.833333 | 19292 | 8350 | 1 |
fig = px.parallel_coordinates(df, dimensions=['brand_name','multiorder_count','order_hour','rest_id','courier_id',
'delta_time','order_items_cnt','city'], color='multiorder_count')
fig.show()
df.groupby('order_items_cnt')[['order_count','multiorder_count']].sum().sort_index(ascending=False).head(60)
| order_count | multiorder_count | |
|---|---|---|
| order_items_cnt | ||
| 108 | 1 | 0 |
| 99 | 1 | 0 |
| 63 | 1 | 0 |
| 61 | 1 | 0 |
| 60 | 2 | 0 |
| 57 | 1 | 0 |
| 54 | 1 | 0 |
| 53 | 1 | 0 |
| 51 | 1 | 0 |
| 46 | 2 | 0 |
| 45 | 2 | 0 |
| 43 | 2 | 0 |
| 42 | 5 | 0 |
| 41 | 1 | 0 |
| 40 | 3 | 0 |
| 39 | 2 | 0 |
| 38 | 1 | 0 |
| 37 | 2 | 0 |
| 36 | 1 | 0 |
| 35 | 2 | 0 |
| 34 | 4 | 0 |
| 33 | 4 | 0 |
| 32 | 4 | 0 |
| 31 | 5 | 0 |
| 30 | 3 | 0 |
| 29 | 7 | 0 |
| 28 | 10 | 0 |
| 27 | 9 | 0 |
| 26 | 16 | 0 |
| 25 | 6 | 0 |
| 24 | 16 | 0 |
| 23 | 20 | 0 |
| 22 | 32 | 1 |
| 21 | 34 | 0 |
| 20 | 59 | 0 |
| 19 | 73 | 0 |
| 18 | 103 | 0 |
| 17 | 99 | 0 |
| 16 | 152 | 1 |
| 15 | 229 | 4 |
| 14 | 306 | 1 |
| 13 | 429 | 5 |
| 12 | 585 | 5 |
| 11 | 873 | 4 |
| 10 | 1248 | 8 |
| 9 | 1838 | 11 |
| 8 | 2724 | 20 |
| 7 | 3934 | 35 |
| 6 | 5900 | 37 |
| 5 | 8299 | 59 |
| 4 | 11562 | 79 |
| 3 | 12592 | 96 |
| 2 | 10863 | 58 |
| 1 | 4393 | 18 |
df.groupby('brand_name')[['order_count','multiorder_count']].sum()
| order_count | multiorder_count | |
|---|---|---|
| brand_name | ||
| 0 | 56835 | 0 |
| 1 | 9629 | 442 |
pd.pivot_table(df,
index=['city'],
columns=['brand_name'],
values=['order_count', 'multiorder_count'],
aggfunc=np.sum).fillna(0)
| multiorder_count | order_count | |||
|---|---|---|---|---|
| brand_name | 0 | 1 | 0 | 1 |
| city | ||||
| 1 | 0.0 | 442.0 | 35822.0 | 4878.0 |
| 2 | 0.0 | 0.0 | 3320.0 | 782.0 |
| 3 | 0.0 | 0.0 | 2249.0 | 616.0 |
| 4 | 0.0 | 0.0 | 2141.0 | 432.0 |
| 5 | 0.0 | 0.0 | 2192.0 | 270.0 |
| 6 | 0.0 | 0.0 | 1324.0 | 387.0 |
| 7 | 0.0 | 0.0 | 970.0 | 442.0 |
| 8 | 0.0 | 0.0 | 1150.0 | 192.0 |
| 9 | 0.0 | 0.0 | 822.0 | 208.0 |
| 10 | 0.0 | 0.0 | 852.0 | 113.0 |
| 11 | 0.0 | 0.0 | 633.0 | 76.0 |
| 12 | 0.0 | 0.0 | 439.0 | 254.0 |
| 13 | 0.0 | 0.0 | 393.0 | 247.0 |
| 14 | 0.0 | 0.0 | 507.0 | 127.0 |
| 15 | 0.0 | 0.0 | 606.0 | 1.0 |
| 16 | 0.0 | 0.0 | 506.0 | 91.0 |
| 17 | 0.0 | 0.0 | 444.0 | 13.0 |
| 18 | 0.0 | 0.0 | 357.0 | 61.0 |
| 19 | 0.0 | 0.0 | 244.0 | 173.0 |
| 20 | 0.0 | 0.0 | 330.0 | 67.0 |
| 21 | 0.0 | 0.0 | 318.0 | 25.0 |
| 22 | 0.0 | 0.0 | 342.0 | 0.0 |
| 23 | 0.0 | 0.0 | 233.0 | 60.0 |
| 24 | 0.0 | 0.0 | 149.0 | 5.0 |
| 25 | 0.0 | 0.0 | 120.0 | 3.0 |
| 26 | 0.0 | 0.0 | 73.0 | 42.0 |
| 27 | 0.0 | 0.0 | 98.0 | 12.0 |
| 28 | 0.0 | 0.0 | 74.0 | 10.0 |
| 29 | 0.0 | 0.0 | 58.0 | 15.0 |
| 30 | 0.0 | 0.0 | 47.0 | 0.0 |
| 31 | 0.0 | 0.0 | 22.0 | 5.0 |
| 32 | 0.0 | 0.0 | 0.0 | 22.0 |
df[df.brand_name==1].groupby(['city'])[['order_count','multiorder_count']].sum().plot()
<AxesSubplot:xlabel='city'>
df[(df.brand_name==1)&(df.city==1)].groupby('courier_id')[['order_count','multiorder_count']].sum().sort_values(
'order_count', ascending=False).head(10)
| order_count | multiorder_count | |
|---|---|---|
| courier_id | ||
| 1 | 414 | 0 |
| 8 | 136 | 0 |
| 5 | 20 | 0 |
| 182 | 10 | 2 |
| 572 | 10 | 0 |
| 162 | 10 | 8 |
| 482 | 8 | 0 |
| 708 | 8 | 0 |
| 172 | 7 | 0 |
| 166 | 7 | 0 |
print('Начало тестирования:', df[df.brand_name==1].order_created_datetime.min())
print('Завершение тестирования:', df[df.brand_name==1].order_created_datetime.max())
print('Период тестирования, в часах:',
int((df[df.brand_name==1].order_created_datetime.max() -
df[df.brand_name==1].order_created_datetime.min()).total_seconds()/60/60))
Начало тестирования: 2015-09-13 00:00:05 Завершение тестирования: 2015-09-16 10:56:48 Период тестирования, в часах: 82
print('Начало периода анализа:', df[df.brand_name==0].order_created_datetime.min())
print('Завершение периода анализа:', df[df.brand_name==0].order_created_datetime.max())
print('Период анализа, в часах:',
int((df[df.brand_name==0].order_created_datetime.max() -
df[df.brand_name==0].order_created_datetime.min()).total_seconds()/60/60))
Начало периода анализа: 2015-09-13 00:00:44 Завершение периода анализа: 2015-09-16 10:56:59 Период анализа, в часах: 82
print('Курьер работает не более 8 часов, выполняет не более 1 обычного заказа в час')
print('Всего рабочих часов за время тестирования (8+8+2):', 8+8+2)
print('В качестве отсечки возьмем удвоенное число заказов на одного курьера:', (8+8+2)*2)
print('Все, что выше - это особые условия доставки')
Курьер работает не более 8 часов, выполняет не более 1 обычного заказа в час Всего рабочих часов за время тестирования (8+8+2): 18 В качестве отсечки возьмем удвоенное число заказов на одного курьера: 36 Все, что выше - это особые условия доставки
# Формируем список спецкурьеров, заказы которых не участвуют в проверке на возможность вкллючения в мультизаказ
temp_df = df.groupby('courier_id').order_count.sum()
list_exclude_couriers = set(temp_df[temp_df>36].index)
len(list_exclude_couriers)
# Проверяем на выборке A, сколько заказов спецкурьеров было объединено в мультизаказ
# Должно быть 0, так как заказы, записанные на спецкурьеров не объединяются в мультизаказ
df[df.courier_id.isin(list_exclude_couriers)].multiorder_count.sum()
0
# Итак, три условия
# 1. Берем только город, где проводился тест (city == 1)
# 2. Берем только заказы c 8:00 до 23:59
# 3. Исключаем спецкурьеров (not .isin(list_exclude_couriers))
# 4. Исключаем заказы с количеством позиций в заказе > 22 (суммарно >27)
# 5. Берем только заказы, у которых разница с предыдущим заказом менее Х минут.
# Х подбираем, минимизируя отклонение от тестовой выборки
df_result = df.merge(df,
left_on = ['co_order'],
right_index=True,
how='left')
df_result.drop(['brand_name_y','rest_id_y','city_y','order_count_y','multiorder_count_y',
'delta_time_y','co_order_y','pair_id_y','co_first_y'], axis=1, inplace=True)
df_result = df_result[df_result.co_first_x==1]
df_result.to_clipboard()
# Заполнение информации о потенциальном мультизаказе
multiorder_id = 0
df_s = df_result.sort_values('delta_time_x')
df_s['multiorder_id'] = 0
n_count = 0
max_n_count = len(df_s)
# Перебираем все заказы
for i in df_s.index:
rec = df_s.loc[i]
# Проверка условий для заказов на отнесение к мультизаказу
if ((rec.city_x==1)
and (not rec.courier_id_x in list_exclude_couriers)
and (not rec.courier_id_y in list_exclude_couriers)
and (rec.order_hour_x > 8)
and (rec.order_hour_x > 8)
and (rec.order_items_cnt_x <= 22)
and (rec.order_items_cnt_y <= 22)
and ((rec.order_items_cnt_x + rec.order_items_cnt_y) <= 27)
and (rec.delta_time_x < 5)):
multiorder_id += 1
df_s.loc[i, 'multiorder_id'] = multiorder_id
n_count += 1
if n_count % 71 == 0:
print(f'Обработано {n_count} записей из {max_n_count}. ', end='\r')
print(f'Обработано {max_n_count} записей из {max_n_count}. Обработка завершена')
Обработано 28546 записей из 28546. Обработка завершена
print('Количество заказов в мультизаказах в группе `A` (проверка)',
len(df_s[(df_s.multiorder_id>0)&(df_s.brand_name_x==1)])*2)
print('Доля мультизаказов в группе `A`',
len(df_s[(df_s.multiorder_id>0)&(df_s.brand_name_x==1)])*2/len(df_input[df_input.brand_name=='A']))
Количество заказов в мультизаказах в группе `A` (проверка) 526 Доля мультизаказов в группе `A` 0.05462664866548966
print('Количество заказов в мультизаказах в группе `B` (проверка)',
len(df_s[(df_s.multiorder_id>0)&(df_s.brand_name_x==0)])*2)
print('Доля мультизаказов в группе `B`',
len(df_s[(df_s.multiorder_id>0)&(df_s.brand_name_x==0)])*2/len(df_input[df_input.brand_name=='B']))
Количество заказов в мультизаказах в группе `B` (проверка) 15066 Доля мультизаказов в группе `B` 0.26508313539192396